home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 2
/
Amiga Tools 2.iso
/
tools
/
mg
/
src.lzh
/
amiga
/
tty.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-23
|
11KB
|
498 lines
/*
* Name: MG 2a Amiga console device virtual terminal display Last
* Edit: 29-Nov-87 mic@emx.cc.utexas.edu Created: 19-Apr-86
* mic@emx.cc.utexas.edu
*
* Drives the Amiga console device display. The code is basically like the
* termcap driver in that it uses the console device scrolling region. It
* also has some hacks to manage the console device colors. The latest hack
* is to inform the terminal I/O driver when we intend to do an escape
* sequence; this allows the terminal I/O driver to turn off the cursor
* without breaking up the sequences, leading to a garbled screen.
*/
#undef MANX
#undef LATTICE
#include "compiler.h"
#include "change_color.h"
#include "mode_fg.h"
#include "mode_bg.h"
#include "mode_rendition.h"
#include "text_fg.h"
#include "text_bg.h"
#include "text_rendition.h"
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/tasks.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <devices/console.h>
#include <libraries/dos.h>
#include <graphics/clip.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <graphics/layers.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#ifndef MANX
#include <intuition/intuitionbase.h>
#endif
#include <intuition/intuition.h>
#undef TRUE
#undef FALSE
#include "def.h"
#ifdef ANSI
#include <stdlib.h>
#endif
#define BEL 0x07 /* BEL character. */
#define ESC 0x1B /* ESC character. */
#define LF 0x0A /* Linefeed character */
#define CSI 0x9B /* Command Sequence Introducer */
extern int ttrow;
extern int ttcol;
extern int tttop;
extern int ttbot;
extern int tthue;
int tceeol = 3; /* Costs, ANSI display. */
int tcinsl = 17;
int tcdell = 16;
#ifdef CHANGE_COLOR
short mode_rendition = MODE_RENDITION, /* set standard colors */
text_rendition = TEXT_RENDITION, text_fg = TEXT_FG + 30, text_bg = TEXT_BG + 40, mode_fg = MODE_FG + 30, mode_bg = MODE_BG + 40;
#else /* colors are hard-coded */
#define mode_rendition MODE_RENDITION
#define text_rendition TEXT_RENDITION
#define text_fg (TEXT_FG + 30)
#define text_bg (TEXT_BG + 40)
#define mode_fg (MODE_FG + 30)
#define mode_bg (MODE_BG + 40)
#endif
#ifdef LATTICE_50
static char a;
#endif
#ifdef LATTICE
VOID
asciiparm(int);
#else
VOID
asciiparm();
#endif
VOID
ttnowindow();
VOID
ttwindow();
/*
* Initialize the terminal when the editor Initialize the virtual terminal.
* Set the console device's top edge below the front-to-back gadgets, to
* avoid garbage when scrolling.
*/
VOID
ttinit()
{
ttputc(CSI);
asciiparm(TOP_OFFSET);
ttputc('y');
}
/*
* Clean up the terminal, in anticipation of a return to the command
* interpreter. This is a no-op on the Amiga, since the window is deleted
* anyway.
*/
VOID
tttidy()
{
}
/*
* Move the cursor to the specified origin 0 row and column position. Try to
* optimize out extra moves; redisplay may have left the cursor in the right
* location last time!
*/
VOID
ttmove(row, col)
{
if (ttrow != row || ttcol != col) {
ttnflush(8); /* flush if buffer too full */
ttputc(CSI);
asciiparm(row + 1);
ttputc(';');
asciiparm(col + 1);
ttputc('H');
ttrow = row;
ttcol = col;
}
}
/*
* Erase to end of line.
*/
VOID
tteeol()
{
ttnflush(2); /* flush if not enough room to fit in buffer */
ttputc(CSI);
ttputc('K');
}
/*
* Erase to end of page.
*/
VOID
tteeop()
{
ttnflush(12); /* flush (but only if not enough room for seq */
ttputc(CSI);
asciiparm((tthue == CTEXT) ? text_rendition : mode_rendition);
ttputc(';');
asciiparm(text_fg);
ttputc(';');
asciiparm(text_bg);
ttputc('m');
ttputc(CSI); /* clear to end of display */
ttputc('J');
}
/*
* Make a noise.
*/
VOID
ttbeep()
{
ttputc(BEL);
ttflush();
}
/*
* Convert a number to decimal ascii, and write it out. Used to deal with
* numeric arguments.
*/
VOID
asciiparm(n)
register int n;
{
if (n > 9)
asciiparm(n / 10);
ttputc((unsigned char) ((n % 10) + '0'));
}
/*
* Insert a block of blank lines onto the screen, using a scrolling region
* that starts at row "row" and extends down to row "bot". Deal with the one
* line case, which is a little bit special, with special case code.
*/
VOID
ttinsl(row, bot, nchunk)
{
if (row == bot) { /* Funny case. */
if (nchunk != 1)
panic("ttinsl: nchunk != 1");
ttmove(row, 0);
tteeol();
return;
}
ttmove(1 + bot - nchunk, 0);
if (nchunk > 0) {
ttwindow(row, bot);
ttnflush(4); /* don't break the sequence */
ttputc(CSI);
asciiparm(nchunk);
ttputc('T'); /* Scroll scrolling region down */
ttnowindow();
}
}
/*
* Delete a block of lines, with the uppermost line at row "row", in a screen
* slice that extends to row "bot". The "nchunk" is the number of lines that
* have to be deleted. It's really easy with the console device scrolling
* region.
*/
VOID
ttdell(row, bot, nchunk)
{
if (row == bot) { /* One line special case */
ttmove(row, 0);
tteeol();
return;
}
if (nchunk > 0) {
ttwindow(row, bot);
ttnflush(4); /* don't break esc. sequence */
ttputc(CSI);
asciiparm(nchunk);
ttputc('S'); /* Scroll scrolling region up */
ttnowindow();
}
ttrow = HUGE;
ttcol = HUGE;
ttmove(bot - nchunk, 0);
}
/*
* This routine sets the scrolling window on the display to go from line
* "top" to line "bot" (origin 0, inclusive). The caller checks for the
* pathalogical 1 line scroll window that doesn't work right on all systems,
* and avoids it. The "ttrow" and "ttcol" variables are set to a crazy value
* to ensure that ttmove() actually does something.
*/
extern struct Window *EmW; /* The window MG uses */
VOID
ttwindow(top, bot)
{
if (tttop != top || ttbot != bot) {
ttnflush(10); /* Flush if necessary */
ttputc(CSI); /* Home cursor */
ttputc('H');
ttputc(CSI); /* Set top offset */
asciiparm(TOP_OFFSET + top * FontHeight(EmW));
ttputc('y');
ttputc(CSI);
asciiparm(bot - top + 1); /* Set page length */
ttputc('t');
ttrow = HUGE; /* Force cursor reset */
ttcol = HUGE;
tttop = top; /* Save region state */
ttbot = bot;
}
}
/*
* Switch to full screen scrolling
*/
VOID
ttnowindow()
{
ttnflush(10); /* Flush if necessary */
ttputc(CSI); /* Home cursor */
ttputc('H');
ttputc(CSI); /* Set top offset to normal */
asciiparm(TOP_OFFSET);
ttputc('y');
ttputc(CSI); /* Set page length to nrow */
asciiparm(nrow);
ttputc('t');
ttrow = HUGE; /* Make cursor unknown. */
ttcol = HUGE;
tttop = HUGE;
ttbot = HUGE;
}
#ifdef CHANGE_COLOR
/*
* Set the rendition of the mode line by selecting colors from the following:
* 0 -- plain text 1 -- bold-face 3 -- italic 4 -- underscore 7 -- inverse
* video Certain of these selections may be less than appealing :-)
*/
ttmode(f, n)
{
register int s;
char buf[2];
if (!(f & FFARG)) {
if ((s = ereply("Set mode line rendition (0-7): ",
buf, sizeof(buf))) != TRUE)
return (s);
n = atoi(buf);
}
if (n < 0 || n > 7)
return (FALSE);
mode_rendition = n; /* store the color */
sgarbf = TRUE;
return (TRUE);
}
/*
* Set the rendition of the text area. Most of these selections will be less
* than appealing :-]
*/
tttext(f, n)
{
register int s;
char buf[2];
if (!(f & FFARG)) {
if ((s = ereply("Set text rendition (0-7): ",
buf, sizeof(buf))) != TRUE)
return (s);
n = atoi(buf);
}
if (n < 0 || n > 7)
return (FALSE);
text_rendition = n; /* store the color */
sgarbf = TRUE;
return (TRUE);
}
/*
* Set foreground color for entire window to a value between 30 and 37, which
* corresponds to the arguments 0-7. This requires a total refresh, which
* sets up the screen.
*/
textforeground(f, n)
{
register int s;
char buf[2];
if (!(f & FFARG)) {
if ((s = ereply("Text foreground color (0-7): ",
buf, sizeof(buf))) != TRUE)
return (s);
n = atoi(buf);
}
if (n < 0 || n > 7)
return (FALSE);
text_fg = n + 30;
sgarbf = TRUE;
return (TRUE);
}
/*
* Set background color for entire window to a value between 40 and 47
* inclusive.
*/
textbackground(f, n)
{
register int s;
char buf[2];
if (!(f & FFARG)) {
if ((s = ereply("Text background color (0-7): ",
buf, sizeof(buf))) != TRUE)
return (s);
n = atoi(buf);
}
if (n < 0 || n > 7)
return (FALSE);
text_bg = n + 40;
sgarbf = TRUE;
return (TRUE);
}
/*
* Set foreground color for entire the mode line
*/
modeforeground(f, n)
{
register int s;
char buf[2];
if (!(f & FFARG)) {
if ((s = ereply("Mode line foreground color (0-7): ",
buf, sizeof(buf))) != TRUE)
return (s);
n = atoi(buf);
}
if (n < 0 || n > 7)
return (FALSE);
mode_fg = n + 30;
sgarbf = TRUE;
return (TRUE);
}
/*
* Set background color for the mode line
*/
modebackground(f, n)
{
register int s;
char buf[2];
if (!(f & FFARG)) {
if ((s = ereply("Mode line background color (0-7): ",
buf, sizeof(buf))) != TRUE)
return (s);
n = atoi(buf);
}
if (n < 0 || n > 7)
return (FALSE);
mode_bg = n + 40;
sgarbf = TRUE;
return (TRUE);
}
#endif
/*
* Set the current writing color to the specified color. Watch for color
* changes that are not going to do anything (the color is already right) and
* don't send anything to the display.
*/
VOID
ttcolor(color)
register int color;
{
if (color != tthue) {
ttnflush(12); /* Flush if necessary */
if (color == CTEXT) { /* Normal video. */
ttputc(CSI); /* Reset to 0 */
ttputc('m');
ttputc(CSI); /* Set text style */
asciiparm(text_rendition);
ttputc(';');
asciiparm(text_fg);
ttputc(';');
asciiparm(text_bg);
ttputc('m');
} else if (color == CMODE) { /* Standout mode */
ttputc(CSI); /* Reset to 0 */
ttputc('m');
ttputc(CSI); /* Set standout mode */
asciiparm(mode_rendition);
ttputc(';');
asciiparm(mode_fg); /* Use mode line colors */
ttputc(';');
asciiparm(mode_bg);
ttputc('m');
}
tthue = color; /* Save the color. */
}
}
/*
* This routine is called by the "refresh the screen" command to try and
* resize the display. The new size, which must be deadstopped to not exceed
* the NROW and NCOL limits, is stored back into "nrow" and "ncol". Display
* can always deal with a screen NROW by NCOL. Look in "window.c" to see how
* the caller deals with a change. On the Amiga, we make the Intuition
* terminal driver do all the work.
*/
VOID
ttresize()
{
setttysize();
}